package ru.avn.devtool4j.spi.writers.impl;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import ru.avn.devtool4j.spi.types.ClassType;
import ru.avn.devtool4j.spi.writers.ClassWriter;
import ru.avn.devtool4j.spi.writers.FieldWriter;
import ru.avn.devtool4j.spi.writers.MethodWritter;

public class ClassWritterImpl implements ClassWriter {

	private List<String> imports = Collections.<String>emptyList();
	private String packageName = null;
	
	private String classname = null;
	private ClassType classType = ClassType.CLASS;
	private int[] modifiers = new int[] {};
	
	private String extend = null;
	
	private List<String> interfaces = Collections.<String>emptyList();
	
	private List<FieldWritterImpl> fieldWritters = Collections.<FieldWritterImpl>emptyList();
	
	@Override
	public ClassWriter setPackage(String packageName) {
		this. packageName = packageName;
		return this;
	}

	@Override
	public ClassWriter addImport(String i) {
		
		if (i == null) {
			throw new IllegalArgumentException();
		}
		
		if (imports.isEmpty()) {
			imports = createList(String.class);
		}
		
		imports.add(i);
		return this;
	}

	@Override
	public ClassWriter addImports(String[] imports) {
		
		if (imports == null) {
			throw new IllegalArgumentException();
		}
		
		if (this.imports.isEmpty()) {
			this.imports = createList(String.class);
		}
		
		for (String i : imports) {
			this.imports.add(i);
		}
		
		return this;
	}

	@Override
	public ClassWriter createClassBody(String className) {
		
		if (className == null) {
			throw new IllegalArgumentException();
		}
		
		this.classname = className;
		return this;
	}
	
	
	@Override
	public ClassWriter createClassBody(String className, ClassType classType) {

		if (className == null) {
			throw new IllegalArgumentException();
		}
		
		if (classType == null) {
			throw new IllegalArgumentException();
		}
		
		this.classname = className;
		this.classType = classType;
		return this;
	}

	@Override
	public ClassWriter createClassBody(String className, ClassType classType, int[] modifiers) {
		
		if (className == null) {
			throw new IllegalArgumentException();
		}
		
		if (modifiers == null) {
			throw new IllegalArgumentException();
		}
		
		if (classType == null) {
			throw new IllegalArgumentException();
		}
		
		this.classname = className;
		
		this.classname = className;
		this.modifiers = modifiers;
		return this;
	}

	@Override
	public FieldWriter addNewField() {
		FieldWritterImpl impl = new FieldWritterImpl();
		if (fieldWritters.isEmpty()) {
			fieldWritters = createList(FieldWritterImpl.class);
		}
		fieldWritters.add(impl);
		return impl;
	}

	@Override
	public MethodWritter addNewMethod() {
		return null;
	}

	@Override
	public <T> T build(Class<T> requiredClass) {
		return null;
	}

	
	@Override
	public Class<?>[] supportedResultTypes() {
		return new Class<?>[] {String.class};
	}

	
	private <T> List<T> createList(Class<T> requiredType) {
		return new LinkedList<T>();
	}
	
	
	public String buildClassCode() {
		DslClassWriter dslWriter = DslClassWriter.getWriter()
			.writeLine("package " + packageName, packageName != null)
			.writeLines(imports);
		
		dslWriter.write(WritterHelper.modifiers(modifiers))
			.write(classType.getValue())
			.write(classname);
		
		dslWriter.write("extends " + extend, extend != null);
		dslWriter.write("implements " + WritterHelper.join(interfaces, ", "), !interfaces.isEmpty());
		
		dslWriter.newBlock();
		
		for (FieldWritterImpl field : fieldWritters) {
			dslWriter.writeLine(field.buildFieldCode());
		}
		
		dslWriter.closeBlock();	
		
		return dslWriter.build();
	}
	
}
